iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 26
0

目標

今天要來學習的是DOM的事件傳遞機制

這邊有一個簡單的html範例

<body class="bod">
    <div class="one">
        <div class="two">
            <div class="three">
            </div>
        </div>
    </div>
<body>

首先,要幫這三個<div>加上事件監聽器

const divs = document.querySelectorAll('div');

function logText(e) {
  console.log(this.classList.value);
}

divs.forEach(div => div.addEventListener('click', logText);

每當點擊<div>的時候,要印出<div>的class

接下來,點擊class為three的<div>

https://ithelp.ithome.com.tw/upload/images/20201009/20121041P2VbfY0Eo4.png

咦?怎麼印出三個class

這是因為當我們點擊第三層<div>,我們同時也點擊到第二層跟第一層,因為它們是一層一層包起來的

這邊我作了一個簡單的示意圖

https://ithelp.ithome.com.tw/upload/images/20201009/20121041IrkAFR9Rv1.png

Capture Phase

當我們點擊一個元素時,瀏覽器會從DOM的根向下捕捉(Capture),一直到我們點擊的元素為止,然後進入冒泡階段(Bubbling Phase)

Bubbling Phase

接續捕捉階段,冒泡階段會從我們點擊的元素開始,向上觸發事件,以今天的範例為例,當我們點擊(click)第三層後,點擊事件會依序向上發動,所以第二層跟第一層也會被觸發

EventTarget.addEventListener()

接下來,讓我們仔細看一下addEventListener()addEventListener()可以傳入三個參數

  • type

    事件種類,e.g. click, mouseenter, keydown, etc.

    可參考:Event reference

  • listener

    當指定類型的事件發生時,接收通知的對象

  • options

    監聽對象的事件監聽器特徵

    • capture

      如果設為true,事件會在捕捉階段觸發listener,預設false

    • once

      如果設為true,在觸發監聽事件後,事件監聽器會被移除

    • passive

      如果為true,則表示監聽器指定的函數(listener)將永遠不會調用preventDefault()

divs.forEach(div => div.addEventListener('click', logText, {
  capture: true,
  once: false
}));

https://ithelp.ithome.com.tw/upload/images/20201009/20121041GYEJSJRhYa.png

那麼要如何阻止事件傳遞呢?

function logText(e) {
  console.log(this.classList.value);
  e.stopPropagation(); // stop bubbling!
}

這邊可以使用stopPropagation()

Event.stopPropagation()

此方法可阻止當前事件繼續進行捕捉(capturing)及冒泡(bubbling)階段的傳遞

https://ithelp.ithome.com.tw/upload/images/20201009/201210413GAOSglbWc.png


上一篇
Day25 -- Sticky Nav
下一篇
Day27 -- Stripe Follow Along Dropdown
系列文
森林系工程師之開始工作才學JS?!32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言